#include "app_router.h"
#include <stdlib.h>
#include <string.h>
#include "thirdparty/log/log.h"
#include "app_mqtt.h"
#include "app_message.h"

#define MAX_DEVICE_COUNT 10

static Device **devices;
static int device_count;

/**
 * @brief MQTT处理消息的回调函数，最终会将消息写入到对应设备缓存
 *
 * @param payload
 * @param payload_length
 * @return int
 */
int app_router_mqttCallback(char *payload, int payload_length)
{
    // 将json str转化为Message
    Message message;
    int result = app_message_initByJson(&message, payload, payload_length);
    if (result < 0)
    {
        log_warn("Failed to init message");
        return -1;
    }

    // 找到对应设备
    Device *device = NULL;
    for (int i = 0; i < device_count; i++)
    {
        if (devices[i]->connection_type == message.connection_type)
        {
            // 找到设备
            device = devices[i];
            break;
        }
    }

    if (!device)
    {
        log_warn("Failed to find device");
        return -1;
    }

    char buf[1024];
    result = app_message_toBinary(&message, buf, sizeof(buf));
    app_message_free(&message);
    if (result < 0)
    {
        log_warn("Failed to convert message to binary");
        return -1;
    }

    // 将Message写入对应设备
    return app_device_write(device, buf, result);
}

/**
 * @brief Device回调函数，将Device缓存中的数据发送到MQTT服务器
 *
 * @param device
 * @param ptr
 * @param len
 * @return int
 */
int app_router_deviceCallback(Device *device, void *ptr, int len)
{
    // 将这个二进制格式的数据转化为message
    Message message;
    char json_buf[1024];
    int result = app_message_initByBinary(&message, ptr, len);
    if (result < 0)
    {
        log_warn("Failed to init message");
        return -1;
    }

    // 将message转化为json
    result = app_message_toJson(&message, json_buf, sizeof(json_buf));
    app_message_free(&message);
    if (result < 0)
    {
        log_warn("Failed to convert message to json");
        return -1;
    }

    // 调用mqtt发送json数据
    return app_mqtt_send(json_buf, strlen(json_buf) + 1);
}

int app_router_init(void)
{
    devices = malloc(sizeof(Device *) * MAX_DEVICE_COUNT);
    if (!devices)
    {
        log_warn("Failed to allocate memory for device list");
        return -1;
    }

    if (app_mqtt_init() < 0)
    {
        log_warn("Failed to init mqtt");
        return -1;
    }

    app_mqtt_registerRecvCallback(app_router_mqttCallback);

    return 0;
}

int app_router_registerDevice(Device *device)
{
    if (device_count >= MAX_DEVICE_COUNT)
    {
        log_warn("Device count exceeds maximum limit");
        return -1;
    }

    devices[device_count++] = device;
    app_device_registerRecvCallback(device, app_router_deviceCallback);
    app_device_start(device);
    return 0;
}

void app_router_close(void)
{
    for (int i = 0; i < device_count; i++)
    {
        app_device_stop(devices[i]);
        app_device_close(devices[i]);
    }

    app_mqtt_close();
    free(devices);
}
